﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using haptic.src.engine.core;
using haptic.src.engine.render;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;
using haptic.src.engine.resource;

namespace haptic.src.engine.sprite
{
    [Serializable]
    public class Sprite : ISprite
    {
        /*#region enum
        public enum State
        {
            E_STOPPED = 0,
            E_PLAYING,
            E_PAUSED
        }
        public enum Mode
        {
            E_LOOP = 0,
            E_PLAY_ONCE,
            E_STAY_ON_LAST_FRAME
        }
        #endregion*/

        #region Constructors
        public Sprite() {}
        public Sprite(string sPath)
        {
            Debug.Assert(sPath != null);
            m_sSpritePath = sPath;
        }
        #endregion

        #region Load
        public Result Load()
        {
            if (m_sSpritePath == null)
                return new Result("The sprite path is null");
            m_oData = ResourceManager.Inst.Get<SpriteData>(m_sSpritePath);
            if (m_oData == null)
                return new Result("Cannot get SpriteData");
            return Result.Success;
        }
        public void Unload()
        {
            m_oData.Unload();
            m_oData = null;
        }
        #endregion

        #region Update
        public void Update(GameTime oTime)
        {
            Debug.Assert(m_oData != null);
            if (m_oData.fTotalDuration != 0.0f)
            {
                float fTimeRatio = m_fElapsedTime / m_oData.fTotalDuration;
                fTimeRatio -= (float)(uint)(fTimeRatio);
                m_uiFrameIndex = (uint)(fTimeRatio * (float)m_oData.m_uiFrameCount);
            }
            m_oRect.Width = (int)m_oData.fFrameWidth;
            m_oRect.Height = (int)m_oData.fFrameHeight;
            m_oRect.X = (int)(m_uiFrameIndex * m_oData.fFrameWidth);
            m_oRect.Y = 0;
        }
        #endregion

        #region Draw
        public void Draw(Renderer oRenderer, Vector2 vPos, float fRot)
        {
            if (m_oData == null)
                return;
            Vector2 vOrigin = vPos;
            vOrigin.X -= m_oData.fFrameWidth * .5f;
            vOrigin.Y -= m_oData.fFrameHeight * .5f;
            oRenderer.DrawSprite(m_oData.oTexture, vOrigin, m_oRect);
        }
        #endregion

        #region Accessors
        public float GetWidth()
        {
            if (m_oData != null)
                return m_oData.fFrameWidth;
            else
                return 0.0f;
        }
        public float GetHeight()
        {
            if (m_oData != null)
                return m_oData.fFrameHeight;
            else
                return 0.0f;
        }
        public float GetSquaredRadius()
        {
            if (m_oData != null)
                return m_oData.fSquaredRadius;
            else
                return 0.0f;
        }
        #endregion

        #region Attributes
        [XmlAttribute("sprite-path")]
        public string m_sSpritePath;
        private uint m_uiFrameIndex = 0;
        private Rectangle m_oRect = new Rectangle(0, 0, 0, 0);
        private float m_fElapsedTime = 0.0f;
        private SpriteData m_oData;
        [XmlAttribute("flip-x")]
        public bool m_bFlipHorizontally = false;
        [XmlAttribute("flip-y")]
        public bool m_bFlipVertically = false;
        private SpriteEffects m_eSpriteEffects = SpriteEffects.None;
        #endregion
    }
}
